package com.honglang.module.article.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.honglang.common.tools.Constants;
import com.honglang.common.tools.Pager;
import com.honglang.module.article.entity.Article;
import com.honglang.module.article.entity.ArticleCategories;
import com.honglang.module.article.entity.BlogArticleComment;
import com.honglang.module.article.entity.BlogArticle;
import com.honglang.module.article.entity.KeyWord;
import com.honglang.module.user.service.UserService;

public class BlogArticleManagerImpl implements BlogArticleManager{
	
	private BlogArticleService blogArticleService;
	
	private ArticleService articleService;
	
	private KeyWordService keyWordService;
	
	private ArticleCategoriesService articleCategoriesService;
	
	private UserService userService;
	
	private BlogArticleCommentService blogArticleCommentService;
	
	
	/**
	 * create a blogArticle from a map which stores the information of the blogArticle;
	 * @param map
	 * @return
	 */
	public BlogArticle createBlogArtilce(Map<String,String> map){
		Article article = new Article();
		article.setTitle(map.get(Constants.Article_Title));
		article.setArticleCategories(articleCategoriesService.getById(Integer.valueOf(map.get(Constants.Article_Category_ID))));
		article.setArticleSource(map.get(Constants.Article_Source));
		article.setAuthor(userService.getUserByUserName(map.get(Constants.USERNAME_KEY)));
		article.setContent(map.get(Constants.Article_Content));
		article.setArticlePreView(map.get(Constants.Article_ArticlePreView));
		Set<KeyWord> keyWordSet = new HashSet<KeyWord>();
		for(String keyWordName : map.get(Constants.Article_KeyWords).split(Constants.KeyWord_Split)){
			KeyWord keyWord = this.keyWordService.getKeyWordByName(keyWordName);
			if (null == keyWord){
				keyWord = new KeyWord();
				keyWord.setName(keyWordName);
				keyWordSet.add(keyWord);
			}else{
				keyWordSet.add(keyWord);
			}
			
		}
		article.setKeyWordSet(keyWordSet);
		article.setWriteDate(new Date());
		BlogArticle blogArticle = new BlogArticle();
		blogArticle.setCommentsCount(0);
		blogArticle.setViewsCount(0);
		blogArticle.setArticle(article);
		blogArticle.setDisplayReadMore(Boolean.valueOf(map.get(Constants.Article_DisplayReadMore)));
		blogArticle.setCommentOpen(Boolean.valueOf(map.get(Constants.Article_CommentOpen)));
		return blogArticle;
	}
	
	
	
	

	/**
	 * update a blogArticle from a map which stores the information of the blogArticle;
	 * @param map
	 * @return
	 */
	public BlogArticle updateBlogArtilce(Map<String,String> map,BlogArticle blogArticle){
		Article article = blogArticle.getArticle();
		article.setTitle(map.get(Constants.Article_Title));
		article.setArticleCategories(articleCategoriesService.getById(Integer.valueOf(map.get(Constants.Article_Category_ID))));
		article.setArticleSource(map.get(Constants.Article_Source));
		article.setAuthor(userService.getUserByUserName(map.get(Constants.USERNAME_KEY)));
		article.setContent(map.get(Constants.Article_Content));
		article.setArticlePreView(map.get(Constants.Article_ArticlePreView));
		Set<KeyWord> keyWordSet = new HashSet<KeyWord>();
		for(String keyWordName : map.get(Constants.Article_KeyWords).split(Constants.KeyWord_Split)){
			KeyWord keyWord = this.keyWordService.getKeyWordByName(keyWordName);
			if (null == keyWord){
				keyWord = new KeyWord();
				keyWord.setName(keyWordName);
				keyWordSet.add(keyWord);
			}else{
				keyWordSet.add(keyWord);
			}
			
		}
		article.setKeyWordSet(keyWordSet);
		article.setWriteDate(new Date());
		blogArticle.setCommentsCount(0);
		blogArticle.setViewsCount(0);
		blogArticle.setArticle(article);
		blogArticle.setDisplayReadMore(Boolean.valueOf(map.get(Constants.Article_DisplayReadMore)));
		blogArticle.setCommentOpen(Boolean.valueOf(map.get(Constants.Article_CommentOpen)));
		return blogArticle;
	}
	
	
	/**
	 * persistence a blogArticle and persistence keyword entity if it doesn't exist
	 * @param blogArticle
	 */
	public void saveBlogArticle(BlogArticle blogArticle){
		this.blogArticleService.save(blogArticle);
	}
	
	
	/**
	 * get all the blogArticles;
	 * @return
	 */
	public List<BlogArticle> getAllBlogArticle(){
		return this.blogArticleService.getAll();
	}
	
	
	/**
	 * get the blogArticle by id;
	 * @param blogArticleId
	 * @return
	 */
	public BlogArticle getBlogAritcleById(Integer blogArticleId){
		return  this.blogArticleService.getBlogArticleById(blogArticleId);
	}
	
	
	
	/**
	 * return the pager of blogArticleList at the page of pageNo;
	 * @param pageSize
	 * @param pageNo
	 * @return
	 */
	public Pager getBlogArticleInPager(int pageSize,int pageNo){
		
		return this.getBlogArticleService().getPager( pageSize, pageNo);
	}
	
	
	
	
	/**
	 * delete blogArticle by id;
	 * @param blogArticleId
	 */
	public void deleteBlogArticle(Integer blogArticleId){
		this.getBlogArticleCommentService().deleteBlogArticleComment(this.getBlogArticleCommentService().getBlogArticleCommentByBlogArticleId(blogArticleId));
		this.getBlogArticleService().deleteBlogArticle(blogArticleId);
	}
	
	
	
	/**
	 * delete blogArticles which id is in the blogArticlesIds;
	 * @param blogArticleIds
	 */
	public void batchDeleteBlogArticle(String blogArticleIds){
		this.getBlogArticleCommentService().deleteBlogArticleComment(this.getBlogArticleCommentService().getBlogArticleCommentByBlogArticleIds(blogArticleIds));
		this.getBlogArticleService().deleteBlogArticleList(this.getBlogArticleService().getBlogArticleByIds(blogArticleIds));
	}
	
	
	
	/**
	 * GET the pager of blogArticleComment ,return the map which include the pager info and comments;
	 * @param pageSize
	 * @param pageNo
	 * @param blogArticleId
	 * @return
	 */
	public Map<String,Object> getBlogArticleCommentPerPage(int pageSize,int pageNo,Integer blogArticleId){
		
		Pager pager = this.getBlogArticleCommentService().getBlogArticleRootCommentsPager(pageSize, pageNo, blogArticleId);
		List<BlogArticleComment> list = new ArrayList<BlogArticleComment>();
		for(Object object : pager.getResultList()){
			BlogArticleComment blogArticleComment= (BlogArticleComment)object;
			list.add(blogArticleComment);
			list.addAll(this.getBlogArticleCommentService().getBlogArticleCommentByRootCommentId(blogArticleComment.getId()));
		}
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("pager", pager);
		map.put("commentList", list);
		return map;
	}
	
	
	

	/**
	 * create a BlogArticleComment from a map which stores the information of the BlogArticleComment;
	 * @param map
	 * @return
	 */
	public BlogArticleComment createComment(Map<String,String> map){
		BlogArticleComment blogArticleComment = new BlogArticleComment();
		blogArticleComment.setAuthor(this.getUserService().getUserByUserName(map.get(Constants.USERNAME_KEY)));
		blogArticleComment.setCommentDate(new Date());
		blogArticleComment.setDisplay(true);
		blogArticleComment.setContent(map.get(Constants.Comment_Content));
		blogArticleComment.setBlogArticle(this.getBlogAritcleById(Integer.valueOf(map.get(Constants.BLOG_ARTICLE_ID))));
		BlogArticleComment comment_parent = this.getBlogArticleCommentService().getBlogArticleCommentById(Integer.valueOf(map.get(Constants.BE_COMMENTED_ID)));
		if(null == comment_parent){
			blogArticleComment.setRootComment(null);
			blogArticleComment.setToComment(null);
		}else{
			blogArticleComment.setToComment(comment_parent);
			blogArticleComment.setRootComment(null == comment_parent.getRootComment()?comment_parent:comment_parent.getRootComment());
		}
		
		return  blogArticleComment;
	}
	
	
	/**
	 * save the blogArticleComment;
	 * @param blogArticleComment
	 * @return
	 */
	public BlogArticleComment saveBlogArticleComment(BlogArticleComment blogArticleComment){
		
		blogArticleComment = this.getBlogArticleCommentService().saveBlogArticleComment(blogArticleComment);
		BlogArticle blogArticle = blogArticleComment.getBlogArticle();
		blogArticle.setCommentsCount(blogArticle.getCommentsCount() +1);
		this.getBlogArticleService().save(blogArticle);
		return blogArticleComment;
	}
	
	
	/**
	 * get the pre blogArticle according  to the article Date;
	 * @param blogArticle
	 * @return
	 */
	public BlogArticle getPreBlogArticle(BlogArticle blogArticle){
		return this.getBlogArticleService().getPreBlogArticleByDate(blogArticle.getArticle().getWriteDate());
	}
	
	
	

	/**
	 * get the next  blogArticle according  to the article Date;
	 * @param blogArticle
	 * @return
	 */
	public BlogArticle getNextBlogArticle(BlogArticle blogArticle){
		return this.getBlogArticleService().getNextBlogArticleByDate(blogArticle.getArticle().getWriteDate());
	}
	
	
	
	
	/**
	 * revert the display property Of blogArticleComment;
	 * @param blogArticleCommentId
	 */
	public void revertCommentDisplay(Integer blogArticleCommentId){
		BlogArticleComment blogArticleComment = this.getBlogArticleCommentService().getBlogArticleCommentById(blogArticleCommentId);
		blogArticleComment.setDisplay(!blogArticleComment.isDisplay());
		this.getBlogArticleCommentService().saveBlogArticleComment(blogArticleComment);
	}
	
	
	public void updateCommentContent(Map<String,String> map,Integer blogArticleCommentId){
		BlogArticleComment blogArticleComment = this.getBlogArticleCommentService().getBlogArticleCommentById(blogArticleCommentId);
		blogArticleComment.setContent(map.get(Constants.Comment_Content));
		blogArticleComment.setLastEditDate(new Date());
		this.getBlogArticleCommentService().saveBlogArticleComment(blogArticleComment);
	}
	
	
	
	/**
	 * get All the category and corresponding count;
	 * @return
	 */
	public List<Map<String,Object>> getCategoriesAndCount(){
		List<ArticleCategories> categoryList = this.getArticleCategoriesService().getAll();
		List<Map<String,Object>> mapList = new ArrayList<Map<String,Object>>();
		for(ArticleCategories ac : categoryList){
			Map<String,Object> map = new HashMap<String,Object>();
			map.put("category", ac);
			map.put("count", this.getBlogArticleService().getArticleCountInOneCategory(ac.getId()));
			mapList.add(map);
		}
		return mapList;
	}
	
	
	
	
	/**
	 * initial the sideBar.ftl data;
	 * @return
	 */
	public Map<Object,Object> initSideBar(){
		Map<Object,Object> map = new HashMap<Object,Object>();
		map.put("mapList", this.getCategoriesAndCount());
		map.put("recentArticleList", this.getBlogArticleService().getRecentBlogArticle(Constants.RECENT_ARTICLE_MAX_RESULT));
		map.put("tagsList", this.getKeyWordService().getAll());
		return map;
	}
	
	
	
	public BlogArticleComment getCommentById(String commentId){
		return this.getBlogArticleCommentService().getBlogArticleCommentById(Integer.valueOf(commentId));
	}
	
	
	
	public BlogArticleService getBlogArticleService() {
		return blogArticleService;
	}

	public void setBlogArticleService(BlogArticleService blogArticleService) {
		this.blogArticleService = blogArticleService;
	}

	public ArticleService getArticleService() {
		return articleService;
	}

	public void setArticleService(ArticleService articleService) {
		this.articleService = articleService;
	}

	public KeyWordService getKeyWordService() {
		return keyWordService;
	}

	public void setKeyWordService(KeyWordService keyWordService) {
		this.keyWordService = keyWordService;
	}



	public ArticleCategoriesService getArticleCategoriesService() {
		return articleCategoriesService;
	}

	public void setArticleCategoriesService(
			ArticleCategoriesService articleCategoriesService) {
		this.articleCategoriesService = articleCategoriesService;
	}


	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}


	public BlogArticleCommentService getBlogArticleCommentService() {
		return blogArticleCommentService;
	}

	public void setBlogArticleCommentService(
			BlogArticleCommentService blogArticleCommentService) {
		this.blogArticleCommentService = blogArticleCommentService;
	}


}
